/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "stdafx.h"
#include "SoundManager.h"
#include <al.h>
#include <al/alut.h>

#include "../kernel.h"

extern Kernel* g_kernel;
/**
====================================================================================================
Sound Manager Subsystem-
OpenAL implementation
====================================================================================================
*/



SoundManager::SoundManager(void)
{
	m_volume    = 0;
    m_mvolume   = 0;
	m_oldVolume = 0;
    m_music     = NULL;

	m_mute   = false;
	m_sounds.clear();
}

/** Initialize the subsystem */
int SoundManager::Init()
{
    g_kernel->GetConsole()->AddCommand( &play_f, "play" );
    g_kernel->GetConsole()->AddCommand( &stop_f, "stop" );
    g_kernel->GetConsole()->AddCommand( &resume_f, "resume" );
    g_kernel->GetConsole()->AddCommand( &sdump_f, "sdump" );

    SetVolume( g_kernel->GetCvars()->GetFloatValue("s_volume") );
    MusicVolume( g_kernel->GetCvars()->GetFloatValue("s_mvolume") );
    
	// initialize openAL
	return !alutInit(NULL, 0);
	
}

/** Update with time elapsed */
void SoundManager::Update(float deltaTime)
{
    // Update the volume each tick
    SetVolume( g_kernel->GetCvars()->GetFloatValue("s_volume") );
    MusicVolume( g_kernel->GetCvars()->GetFloatValue("s_mvolume") );

    // Location of the camera
    Vector2f camPos = g_kernel->GetRenderer()->GetCamera( 0 )->GetPosition();

    camPos = camPos + Vector2f( 400, 300 );
    float f[3];
    f[0] = camPos.x; f[1] = camPos.y; f[2] = 0;
    alListenerfv(AL_POSITION, f );
    alListenerf( AL_GAIN, 1.0f );

	// Update each sound
	for(int i = 0; i < m_sounds.size(); i++ ) {
		m_sounds[i]->Update( deltaTime );
	}

    
}
/** Close off the system */
void SoundManager::Shutdown()
{
    g_kernel->GetConsole()->RemoveCommand( "play" );
    g_kernel->GetConsole()->RemoveCommand( "resume" );
    g_kernel->GetConsole()->RemoveCommand( "stop" );
    g_kernel->GetConsole()->RemoveCommand( "sdump" );

    RemoveAll();
	// close off
	alutExit();
}

/** Set the Volume of all sounds 
 *  0 - 1.0
 */
void SoundManager::SetVolume(float v)
{
	// Set the sound for each source
	for(int i = 0; i < m_sounds.size(); i++ ) {
		m_sounds[i]->Volume( v );
	}
	// set volume
	m_volume = v;
}

/** Toggle Mute */
void SoundManager::Mute(bool b)
{
	m_mute = b;
	if ( m_mute ) {
		m_oldVolume = m_volume;
		SetVolume( 0 );
	} else {
		SetVolume( m_oldVolume );
	}

}


/** Play a music file */
void SoundManager::PlayMusic( const std::string &file )
{
    if ( m_music ) {
	    // clear the old music if any
        RemoveSound( m_music );
        m_music = NULL;
    }

	// load the new file
    m_music = LoadSound( file );

    if ( m_music )
    {
    // Set the volume
    m_music->Volume( GetMusicVolume() );

	// Play the music
	m_music->Play( true );
    }

}
/** Stop the current Music */
void SoundManager::StopMusic()
{
    if ( m_music )
    {
	    // stop the music
	    if ( m_music->IsPlaying() )
		    m_music->Stop();
    }
}

/** Stop the current Music */
void SoundManager::ResumeMusic()
{
    if ( m_music )
    {
	    // stop the music
	    if ( m_music->IsPaused() || m_music->IsStopped() )
		    m_music->Resume();
    }
}

/** Stop all the sounds */
void SoundManager::StopAll()
{
    // Set the sound for each source
	for(int i = 0; i < m_sounds.size(); i++ ) {
        m_sounds[i]->Stop();
	}

}

/** Resume all the sounds */
void SoundManager::ResumeAll()
{
    // Set the sound for each source
	for(int i = 0; i < m_sounds.size(); i++ ) {
        m_sounds[i]->Resume();
	}
}

SoundManager::~SoundManager(void)
{
    
}


/**
=====================================================================================================
Play Command- Play a sound through the console
=====================================================================================================
*/

void Play_f::Exec( std::string & s)
{
    // the sound maybe held by another
    // entity so dont delete it!
    if ( m_sound )
    {
        m_sound->Stop();
        // delete m_sound;
    }
    // load the sound
    m_sound = g_kernel->GetResource()->LoadSound( s );

    if ( m_sound )
    {     
        g_kernel->LPrintf( (s+" Sound Loaded!").c_str() );
        m_sound->Volume ( g_kernel->GetSound()->GetVolume() );
        m_sound->Play( false );
    } else
        g_kernel->LPrintf( (s+" Failed to Load!").c_str() );

}

/**
=====================================================================================================
Stop Command- Stop a sound through the console
=====================================================================================================
*/

void Stop_f::Exec( std::string &s )
{
    g_kernel->GetSound()->StopAll();
}

/**
=====================================================================================================
Resume Command- Resume a sound through the console
=====================================================================================================
*/

void Resume_f::Exec( std::string &s )
{
    g_kernel->GetSound()->ResumeAll();
}

/**
=====================================================================================================
Sound Dump - Remove all sounds from memory
=====================================================================================================
*/

void S_dump_f::Exec(std::string &s)
{
    g_kernel->GetSound()->RemoveAll();

    //g_kernel->GetSound()->Shutdown();
    //g_kernel->GetSound()->Init();

    //g_kernel->GetRenderer()->Shutdown();
    //g_kernel->GetRenderer()->Init();
}